package com.lj.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.lj.common.annotation.datascope.DataScope;
import com.lj.common.core.ajax.Result;
import com.lj.common.core.model.system.SysUser;
import com.lj.common.enums.datascope.DataScopeVersionEnum;
import com.lj.common.exception.ServiceException;
import com.lj.common.utils.security.SecurityUtil;
import com.lj.system.constants.UserConstants;
import com.lj.system.mapper.SysUserMapper;
import com.lj.system.model.SysUserPost;
import com.lj.system.model.SysUserRole;
import com.lj.system.service.ISysUserPostService;
import com.lj.system.service.ISysUserRoleService;
import com.lj.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

import static com.lj.common.utils.security.SecurityUtil.getUserId;

/**
 * 系统配置服务实现类
 *
 * @author 小李飞刀
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private ISysUserPostService userPostService;

    @Resource
    private ISysUserRoleService userRoleService;

    /**
     * 根据用名查询用户信息
     *
     * @param username 用户名
     * @return 结果
     */
    @Override
    public SysUser selectUserByUserName(String username) {
        QueryWrapper<SysUser> queryWrapper = Wrappers.query();
        queryWrapper.eq("user_name", username);
        List<SysUser> userList = this.list(queryWrapper);
        if (CollUtil.isNotEmpty(userList)) {
            return userList.get(0);
        }
        return null;
    }

    /**
     * 校验用户是否有数据权限
     *
     * @param userId 用户ID
     */
    @Override
    public void checkUserDataScope(Long userId) {
        if (!SysUser.isAdmin(getUserId())) {
            List<SysUser> users = this.selectUserList(userId);
            if (CollUtil.isEmpty(users)) {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }
    }

    /**
     * 校验用户名是否唯一
     *
     * @param userName 用户名
     * @return 结果
     */
    @Override
    public boolean checkUserNameUnique(String userName) {
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        return this.count(wrapper.eq(UserConstants.COLUMN_USER_NAME, userName)) == 0L;
    }

    /**
     * 校验用户手机号是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean checkPhoneUnique(SysUser user) {
        Long userId = ObjectUtil.isNull(user.getUserId()) ? -1L : user.getUserId();
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        wrapper.eq(UserConstants.COLUMN_PHONE_NUMBER, user.getPhoneNumber());
        List<SysUser> infoList = this.list(wrapper);
        return (CollUtil.isEmpty(infoList) || ObjectUtil.equals(infoList.get(0).getUserId(), userId));
    }

    /**
     * 校验用户邮箱是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean checkEmailUnique(SysUser user) {
        Long userId = ObjectUtil.isNull(user.getUserId()) ? -1L : user.getUserId();
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        wrapper.eq(UserConstants.COLUMN_EMAIL, user.getEmail());
        List<SysUser> infoList = this.list(wrapper);
        return (CollUtil.isEmpty(infoList) || ObjectUtil.equals(infoList.get(0).getUserId(), userId));
    }

    /**
     * 新增用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public Result addUser(SysUser user) {
        Result uniqueResult = this.checkUnique(user, Boolean.TRUE);
        if (HttpStatus.HTTP_OK != Integer.parseInt(uniqueResult.get(Result.CODE_TAG).toString())) {
            return uniqueResult;
        }
        user.setPassword(SecurityUtil.encryptPassword(user.getPassword()));
        boolean addFlag = this.save(user);
        this.savePostAndRole(user);
        if (addFlag) {
            return Result.success();
        } else {
            return Result.error();
        }
    }


    /**
     * 修改用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public Result updateUser(SysUser user) {
        Result uniqueResult = this.checkUnique(user, Boolean.FALSE);
        if (HttpStatus.HTTP_OK != Integer.parseInt(uniqueResult.get(Result.CODE_TAG).toString())) {
            return uniqueResult;
        }
        SysUser oldUser = this.getById(user.getUserId());
        user.setPassword(oldUser.getPassword());
        // 删除用户角色|岗位关系
        this.delPostAndRole(user);
        // 重新绑定用户角色|岗位关系
        this.savePostAndRole(user);
        boolean updateFlag = this.updateById(user);
        if (updateFlag) {
            return Result.success();
        } else {
            return Result.error();
        }
    }

    /**
     * 判断是否可以操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SysUser user) {
        if (ObjectUtil.isNotNull(user.getUserId()) && user.isAdmin()) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    /**
     * 重置密码
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean resetPwd(SysUser user) {
        SysUser dbUser = this.getById(user.getUserId());
        dbUser.setPassword(SecurityUtil.encryptPassword(user.getPassword()));
        return this.updateById(dbUser);
    }

    /**
     * 修改状态
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean updateUserStatus(SysUser user) {
        SysUser dbUser = this.getById(user.getUserId());
        dbUser.setStatus(user.getStatus());
        return this.updateById(dbUser);
    }

    /**
     * 删除用户岗位|角色关系
     *
     * @param user 用户信息
     */
    private void delPostAndRole(SysUser user) {
        // 删除原来角色用户关系
        QueryWrapper<SysUserPost> postQuery = Wrappers.query();
        postQuery.eq(UserConstants.COLUMN_USER_ID, user.getUserId());
        userPostService.remove(postQuery);
        // 删除原来用户岗位关系
        QueryWrapper<SysUserRole> roleQuery = Wrappers.query();
        roleQuery.eq(UserConstants.COLUMN_USER_ID, user.getUserId());
        userRoleService.remove(roleQuery);
    }

    /**
     * 保存用户岗位|角色关系
     *
     * @param user 用户信息
     */
    private void savePostAndRole(SysUser user) {
        // 判断是否绑定岗位信息
        if (CollUtil.isNotEmpty(user.getPostIds())) {
            this.saveUserPosts(user);
        }
        // 判断是否绑定角色信息
        if (CollUtil.isNotEmpty(user.getRoleIds())) {
            this.saveUserRoles(user);
        }
    }


    /**
     * 判断用户账号|手机号|邮箱是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    private Result checkUnique(SysUser user, boolean addFlag) {
        if (!this.checkUserNameUnique(user.getUserName()) && addFlag) {
            return Result.error("登录账号已存在");
        } else if (CharSequenceUtil.isNotEmpty(user.getPhoneNumber()) && !this.checkPhoneUnique(user)) {
            return Result.error("手机号码已存在");
        } else if (CharSequenceUtil.isNotEmpty(user.getEmail()) && !this.checkEmailUnique(user)) {
            return Result.error("邮箱账号已存在");
        }
        return Result.success();
    }

    /**
     * 保存用户角色关系
     *
     * @param user 用户信息
     */
    private void saveUserPosts(SysUser user) {
        List<SysUserPost> userPosts = Lists.newArrayListWithExpectedSize(user.getPostIds().size());
        for (Long postId : user.getPostIds()) {
            SysUserPost userPost = new SysUserPost();
            userPost.setUserId(user.getUserId());
            userPost.setPostId(postId);
            userPosts.add(userPost);
        }
        userPostService.saveBatch(userPosts);
    }

    /**
     * 保存用户角色关系
     *
     * @param user 用户信息
     */
    private void saveUserRoles(SysUser user) {
        List<SysUserRole> userRoles = Lists.newArrayListWithExpectedSize(user.getRoleIds().size());
        for (Long roleId : user.getRoleIds()) {
            SysUserRole userRole = new SysUserRole();
            userRole.setUserId(user.getUserId());
            userRole.setRoleId(roleId);
            userRoles.add(userRole);
        }
        userRoleService.saveBatch(userRoles);
    }

    /**
     * 查看用户列表
     *
     * @param userId 用户ID
     * @return 结果
     */
    @DataScope(version = DataScopeVersionEnum.PARAMETER)
    private List<SysUser> selectUserList(Long userId) {
        return userMapper.selectUserListByUserId(userId);
    }
}
